package com.act.moudles.act.compents;


import com.act.moudles.act.pojo.TaskSearchPojo;
import com.act.moudles.act.vo.TaskVo;
import com.act.moudles.baseAct.dao.OnlineDeployDao;
import com.act.moudles.baseAct.entity.OnlineDeploy;
import com.act.moudles.user.entity.User;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.persistence.entity.HistoricProcessInstanceEntityImpl;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工作流通用组件封装
 */
@Component
public class ActCompent {


    @Resource
    private OnlineDeployDao onlineDeployDao;


    /**
     * 任务服务，用于管理，查询任务，例如：签收，办理，指派等
     * 是用来可以用来领取，完成，查询任务列表功能的
     */
    @Resource
    private org.activiti.engine.TaskService taskService;


    /**
     * 检查流程权限
     * @param userFlowKey
     * @param user
     * @return
     * @throws Exception
     */
    public String checkAndToFlowKey(String userFlowKey,String tenantId)throws Exception{
        //1.查询流程部署信息
        OnlineDeploy onlineDeploy = onlineDeployDao.selectByUserFlowKey(userFlowKey);
        if(onlineDeploy == null){
            throw new RuntimeException("流程不存在(1)");
        }
        if(!onlineDeploy.getTenantId().equals(tenantId)){
            throw new RuntimeException("流程不存在(2)");
        }
        return  onlineDeploy.getProcdefKey();
    }




    /**
     * 构建历史记录
     * @param taskList
     * @return
     */
    public List<TaskVo> buildTaskHistVo(List<HistoricTaskInstance> taskList){
        if(CollectionUtils.isEmpty(taskList)){
            return new ArrayList<>();
        }
        //1.查询部署流程
        List<String> defIdList = taskList.stream().map(HistoricTaskInstance::getProcessDefinitionId).collect(Collectors.toList());
        LambdaQueryWrapper<OnlineDeploy> query = new LambdaQueryWrapper<>();
        query.in(OnlineDeploy::getProcdefId,defIdList);
        List<OnlineDeploy>  depList = onlineDeployDao.selectList(query);
        Map<String,OnlineDeploy> defIdNameMap = new HashMap<String,OnlineDeploy>(){{
            depList.forEach(o->{
                put(o.getProcdefId(),o);
            });
        }};

        List<TaskVo> voList = new ArrayList<>();
        for(HistoricTaskInstance task : taskList){
            OnlineDeploy dep = defIdNameMap.get(task.getProcessDefinitionId());
            TaskVo vo = TaskVo.builder()
                    .assginee(task.getAssignee())
                    .tenantId(task.getTenantId())
                    .procId(task.getProcessInstanceId())
                    .taskName(task.getName())
                    .endTime(task.getEndTime())
                    .startTime(task.getStartTime())
                    .deployName(dep == null ? null:dep.getDepeloyName())
                    .userFlowKey(dep == null ? null:dep.getUserProcdefKey())
                    .build();
            voList.add(vo);
        }

        //3.查询当前任务所在的节点
        List<String> procIdList = voList.stream().map(TaskVo::getProcId).collect(Collectors.toList());
        List<Task> tasks =  taskService.createTaskQuery().processInstanceIdIn(procIdList).list();
        Map<String,List<Task>> procIdMap = tasks.stream().collect(Collectors.groupingBy(Task::getProcessInstanceId));
        for(TaskVo vo : voList){
            List<Task> tempList = procIdMap.get(vo.getProcId());
            if(!CollectionUtils.isEmpty(tempList)){
                vo.setNowDealTaskList(tempList.stream().map(Task::getName).collect(Collectors.toList()));
                vo.setNowDealUserList(tempList.stream().map(Task::getAssignee).collect(Collectors.toList()));
                vo.buildNow();
            }
        }
        return voList;
    }

    /**
     * 构建历史记录
     * @param taskList
     * @return
     */
    public List<TaskVo> buildProcHistVo(List<HistoricProcessInstance> taskList, TaskSearchPojo pojo){
        if(CollectionUtils.isEmpty(taskList)){
            return new ArrayList<>();
        }
        //1.查询部署流程
        List<String> defIdList = taskList.stream().map(HistoricProcessInstance::getProcessDefinitionId).collect(Collectors.toList());
        LambdaQueryWrapper<OnlineDeploy> query = new LambdaQueryWrapper<>();
        query.in(OnlineDeploy::getProcdefId,defIdList);
        List<OnlineDeploy>  depList = onlineDeployDao.selectList(query);
        Map<String,OnlineDeploy>  defIdNameMap = new HashMap<String,OnlineDeploy>(){{
            depList.forEach(o->{
                put(o.getProcdefId(),o);
            });
        }};

        //2.构建返回数据
        List<TaskVo> voList = new ArrayList<>();
        for(HistoricProcessInstance task : taskList){
            OnlineDeploy dep = defIdNameMap.get(task.getProcessDefinitionId());
            TaskVo vo = TaskVo.builder()
                    .assginee(pojo.getAssginee())
                    .tenantId(task.getTenantId())
                    .procId(((HistoricProcessInstanceEntityImpl) task).getProcessInstanceId())
                    .startTime(task.getStartTime())
                    .endTime(task.getEndTime())
                    .deployName(dep == null ?null:dep.getDepeloyName())
                    .userFlowKey(dep == null ?null:dep.getUserProcdefKey())
                    .build();
            voList.add(vo);
        }

        //3.查询当前任务所在的节点
        List<String> procIdList = voList.stream().map(TaskVo::getProcId).collect(Collectors.toList());
        List<Task> tasks =  taskService.createTaskQuery().processInstanceIdIn(procIdList).list();
        Map<String,List<Task>> procIdMap = tasks.stream().collect(Collectors.groupingBy(Task::getProcessInstanceId));
        for(TaskVo vo : voList){
            List<Task> tempList = procIdMap.get(vo.getProcId());
            if(!CollectionUtils.isEmpty(tempList)){
                vo.setNowDealTaskList(tempList.stream().map(Task::getName).collect(Collectors.toList()));
                vo.setNowDealUserList(tempList.stream().map(Task::getAssignee).collect(Collectors.toList()));
                vo.buildNow();
            }
        }
        return voList;
    }


    /**
     * 构建VO
     * @param tasks
     * @return
     */
    public List<TaskVo> buildTaskVo(List<Task> tasks){
        if(CollectionUtils.isEmpty(tasks)){
            return new ArrayList<>();
        }
        //1.查询部署流程
        List<String> defIdList = tasks.stream().map(Task::getProcessDefinitionId).collect(Collectors.toList());
        LambdaQueryWrapper<OnlineDeploy> query = new LambdaQueryWrapper<>();
        query.in(OnlineDeploy::getProcdefId,defIdList);
        List<OnlineDeploy>  depList = onlineDeployDao.selectList(query);
        Map<String,OnlineDeploy>  defIdNameMap = new HashMap<String,OnlineDeploy>(){{
            depList.forEach(o->{
                put(o.getProcdefId(),o);
            });
        }};

        List<TaskVo> voList = new ArrayList<>();
        for(Task task : tasks){
            OnlineDeploy dep = defIdNameMap.get(task.getProcessDefinitionId());
            TaskVo vo = TaskVo.builder()
                    .assginee(task.getAssignee())
                    .tenantId(task.getTenantId())
                    .procId(task.getProcessInstanceId())
                    .taskName(task.getName())
                    .startTime(task.getCreateTime())
                    .deployName(dep  == null ? null : dep.getDepeloyName())
                    .userFlowKey(dep == null? null: dep.getUserProcdefKey())
                    .build();
            voList.add(vo);
        }
        return voList;
    }


}
